﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using NUnit.Framework;
using Studio7i.Persistencia.ADO;
using Studio7i.Dominio;
using Studio7i.Persistencia;
using Studio7i.Persistencia.NH;

namespace Studio7i.Pruebas
{
    [TestFixture]
    public class Test2_SalaDAO
    {
        // Atributos a utilizar durante las pruebas
        private ISalaDAO salaDAO = null;
        private int codigoGenerado = 0;

        [TestFixtureSetUp]
        public void PrepararPruebas()
        {
            // 1. Definimos la implementación del DAO a probar (ADO / NH / EF)
            salaDAO = new Persistencia.ADO.SalaDAO();
            // 2. Eliminamos todos los locales en BD antes de las pruebas
            foreach (Sala sala in salaDAO.ListarTodos())
                salaDAO.Eliminar(sala);
            // 3. Creamos 2 locales para tenerlos disponibles en las pruebas
            salaDAO.Crear(new Sala() { Nombre = "Rock 80s", Caracteristicas = "Premium", Capacidad = 8, Local = new Local() { Codigo = 1 }, Comentarios = "Zzz..." });
            salaDAO.Crear(new Sala() { Nombre = "Electrónico 90s", Caracteristicas = "VIP", Capacidad = 6, Local = new Local() { Codigo = 2 } });
        }
        [Test]
        public void Test1_Crear()
        {
            // 1. Clase a probar: SalaDAO
            Assert.IsNotNull(salaDAO);
            // 2. Declaramos e instanciamos la entidad de dominio
            Sala salaACrear = new Sala();
            salaACrear.Nombre = "Elvis Lives";
            salaACrear.Caracteristicas = "Magic";
            salaACrear.Capacidad = 4;
            salaACrear.Local = new Local() { Codigo = 1 };
            salaACrear.Comentarios = "Sin comentarios";
            // 3. Declaramos la entidad que contendrá el resultado
            Sala salaCreada = null;
            // 4. Probamos que no ocurra error al ejecutar el método
            Assert.DoesNotThrow(delegate
            {
                // 5. Ejecutamos el método a probar
                salaCreada = salaDAO.Crear(salaACrear);
                codigoGenerado = salaCreada.Codigo;
            });
            // Probamos que la entidad resultante no sea nula
            Assert.IsNotNull(salaCreada);
            // Probamos que el código generado sea mayor a 0
            Assert.Greater(salaCreada.Codigo, 0);
            // Probamos que el nombre registrado es igual al solicitado con la entidad
            Assert.AreEqual(salaCreada.Nombre, salaACrear.Nombre);
            // Probamos que la característica registrada es igual a la solicitada con la entidad
            Assert.AreEqual(salaCreada.Caracteristicas, salaACrear.Caracteristicas);
        }
        [Test]
        public void Test2_Obtener()
        {
            // 1. Clase a probar: LocalDAO
            Assert.IsNotNull(salaDAO);
            // 2. Definimos los datos para la prueba
            int codigo = codigoGenerado;
            // 3. Declaramos la entidad que contendrá el resultado
            Sala salaObtenida = null;
            // 4. Probamos que no ocurra error al ejecutar el método
            Assert.DoesNotThrow(delegate
            {
                // 5. Ejecutamos el método a probar
                salaObtenida = salaDAO.Obtener(codigo);
            });
            // Probamos que la entidad resultante no sea nula
            Assert.IsNotNull(salaObtenida);
            Assert.AreEqual(salaObtenida.Codigo, codigo);
            Assert.IsNotNullOrEmpty(salaObtenida.Nombre);
            Assert.IsNotNullOrEmpty(salaObtenida.Caracteristicas);
        }
        [Test]
        public void Test3_Modificar()
        {
            // 1. Clase a probar: LocalDAO
            Assert.IsNotNull(salaDAO);
            // 2. Declaramos e instanciamos la entidad de dominio
            Sala salaAModificar = salaDAO.Obtener(codigoGenerado);
            salaAModificar.Nombre = "Elvis Lived!";
            salaAModificar.Caracteristicas = "Old Fashion";
            // 3. Declaramos la entidad que contendrá el resultado
            Sala salaModificada = null;
            // 4. Probamos que no ocurra error al ejecutar el método
            Assert.DoesNotThrow(delegate
            {
                // 5. Ejecutamos el método a probar
                salaModificada = salaDAO.Modificar(salaAModificar);
            });
            // Probamos que la entidad resultante no sea nula
            Assert.IsNotNull(salaModificada);
            // Probamos que el código generado sea mayor a 0
            Assert.AreEqual(salaModificada.Codigo, codigoGenerado);
            // Probamos que el nombre registrado es igual al solicitado con la entidad
            Assert.AreEqual(salaModificada.Nombre, salaAModificar.Nombre);
            // Probamos que la característica registrada es igual a la solicitada con la entidad
            Assert.AreEqual(salaModificada.Caracteristicas, salaAModificar.Caracteristicas);
        }
        [Test]
        public void Test4_Eliminar()
        {
            // 1. Clase a probar: LocalDAO
            Assert.IsNotNull(salaDAO);
            // 2. Definimos la entidad que contendrá el resultado
            Sala salaExistente = salaDAO.Obtener(codigoGenerado);
            // 3. Probamos que no ocurra error al ejecutar el método
            Assert.DoesNotThrow(delegate
            {
                // 5. Ejecutamos el método a probar
                salaDAO.Eliminar(salaExistente);
            });
            // Probamos que la entidad ya no existe
            Assert.IsNull(salaDAO.Obtener(codigoGenerado));
        }
        [Test]
        public void Test5_ListarTodos()
        {
            // 1. Clase a probar: LocalDAO
            Assert.IsNotNull(salaDAO);
            // 2. Declaramos la entidad que contendrá el resultado
            ICollection<Sala> salasEncontradas = null;
            // 3. Probamos que no ocurra error al ejecutar el método
            Assert.DoesNotThrow(delegate
            {
                // 5. Ejecutamos el método a probar
                salasEncontradas = salaDAO.ListarTodos();
            });
            // Probamos que la entidad resultante no sea nula
            Assert.IsNotNull(salasEncontradas);
            // Probamos que la cantidad de locales encontrados sea 2
            Assert.AreEqual(salasEncontradas.Count, 2);
            // Probamos que cada local contenga la cadena de búsqueda en su nombre
            foreach (Sala salaEncontrada in salasEncontradas)
            {
                Assert.IsNotNull(salaEncontrada);
                Assert.IsInstanceOf(typeof(Sala), salaEncontrada);
            }
        }
        [Test]
        public void Test6_ListarXBusqueda()
        {
            // 1. Clase a probar: LocalDAO
            Assert.IsNotNull(salaDAO);
            // 2. Definimos los datos para la prueba
            string nombre = "ock"; // Rock *
            // 3. Declaramos la entidad que contendrá el resultado
            ICollection<Sala> salasEncontradas = null;
            // 4. Probamos que no ocurra error al ejecutar el método
            Assert.DoesNotThrow(delegate
            {
                // 5. Ejecutamos el método a probar
                salasEncontradas = salaDAO.ListarXBusqueda(null, nombre, null, null, null, null);
            });
            // Probamos que la entidad resultante no sea nula
            Assert.IsNotNull(salasEncontradas);
            // Probamos que la cantidad de locales encontrados sea 2
            Assert.AreEqual(salasEncontradas.Count, 1);
            // Probamos que cada local contenga la cadena de búsqueda en su nombre
            foreach (Sala salaEncontrada in salasEncontradas)
            {
                Assert.IsTrue(salaEncontrada.Nombre.Contains(nombre));
            }
        }
        [TestFixtureTearDown]
        public void TerminarPruebas()
        {
            NHibernateHelper.CerrarFabrica();
        }
    }
}